package com.sanyou.springcloud.ribbon;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractServerList;
import com.netflix.loadbalancer.Server;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ribbon整合springcloud的ServerList的实现
 * 不能跟启动引导类在同一个目录或者子目录下
 *
 * @author zhuoziyang
 * @date 2021/9/25 21:22
 */
public class SpringCloudServerList extends AbstractServerList<Server> {

    private final DiscoveryClient discoveryClient;

    private String serviceId;

    public SpringCloudServerList(DiscoveryClient discoveryClient) {
        this.discoveryClient = discoveryClient;
    }

    @Override
    public List<Server> getInitialListOfServers() {
        return obtainServerList();
    }

    @Override
    public List<Server> getUpdatedListOfServers() {
        return obtainServerList();
    }

    private List<Server> obtainServerList() {
        List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);

        if (CollectionUtils.isEmpty(instances)) {
            return Collections.emptyList();
        }

        return instances.stream().map(SpringCloudServer::new).collect(Collectors.toList());
    }

    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {
        this.serviceId = clientConfig.getClientName();
    }

    private static class SpringCloudServer extends Server {

        private final MetaInfo metaInfo;

        public SpringCloudServer(ServiceInstance serviceInstance) {
            super(serviceInstance.getHost(), serviceInstance.getPort());
            this.metaInfo = new MetaInfo() {

                @Override
                public String getAppName() {
                    return serviceInstance.getServiceId();
                }

                @Override
                public String getServerGroup() {
                    return null;
                }

                @Override
                public String getServiceIdForDiscovery() {
                    return null;
                }

                @Override
                public String getInstanceId() {
                    return serviceInstance.getInstanceId();
                }
            };
        }

        @Override
        public MetaInfo getMetaInfo() {
            return metaInfo;
        }
    }

}
